#include "unity.h"
#include "mock_bsp_test_commom.h" // CMock 生成的 mock 头文件
#include "Rt_LUT_Config.h"

// 测试用例变量声明
XRt1553B testInstance;
u8 testData[10] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA};

void setUp(void)
{
    // 每个测试用例执行前的初始化
    memset(&testInstance, 0, sizeof(XRt1553B));
    testInstance.BaseAddress = 0x1000;
}

void tearDown(void)
{
    // 每个测试用例执行后的清理
}

/**
 * @brief TC001: 测试数据长度超过有效长度的情况
 * 预期结果: 返回0，不调用XRt1553B_WriteMem
 */
void test_XRt1553B_TxToSubAddr_WhenByteLengthExceedsValidBytes_ShouldReturnZero(void)
{
    u32 subAddr = 1;
    u32 byteLength = 10;

    // 设置有效数据字节数小于请求字节数
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = 5;

    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, testData, byteLength);

    TEST_ASSERT_EQUAL(0, result);
}

/**
 * @brief TC002: 测试偶数字节长度数据发送
 * 预期结果: 正确发送所有字节，返回发送字节数
 */
void test_XRt1553B_TxToSubAddr_WithEvenByteLength_ShouldSendAllBytes(void)
{
    u32 subAddr = 2;
    u32 byteLength = 8;
    u32 startPtr = 0x100;

    // 配置测试环境
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = 10;
    testInstance.tx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;

    // 期望调用XRt1553B_WriteMem四次（每次写入一个u16）
    for (int i = 0; i < 4; i++)
    {
        XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr + i, ((u16 *)testData)[i]);
    }

    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, testData, byteLength);

    TEST_ASSERT_EQUAL(8, result); // 4个word = 8个字节
}

/**
 * @brief TC003: 测试奇数字节长度数据发送
 * 预期结果: 丢弃最后一个字节，返回实际发送字节数
 */
void test_XRt1553B_TxToSubAddr_WithOddByteLength_ShouldDiscardLastByte(void)
{
    u32 subAddr = 3;
    u32 byteLength = 7;  // 奇数
    u32 startPtr = 0x200;

    // 配置测试环境
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = 10;
    testInstance.tx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;

    // 期望调用XRt1553B_WriteMem三次（7-1=6字节，3个word）
    for (int i = 0; i < 3; i++) {
        XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr + i, ((u16*)testData)[i]);
    }

    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, testData, byteLength);

    TEST_ASSERT_EQUAL(6, result); // 3个word = 6个字节
}

/**
 * @brief TC004: 测试循环缓冲区模式下的指针重置
 * 预期结果: 执行指针重置操作
 */
void test_XRt1553B_TxToSubAddr_InCircularBufferMode_ShouldResetPointers(void)
{
    u32 subAddr = 4;
    u32 byteLength = 4;
    u32 startPtr = 0x300;

    // 配置测试环境
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = 10;
    testInstance.tx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    testInstance.tx_SAcfg[subAddr].mm_mode = XRT53_MM_CIRCULAR_BUFFER;

    // 期望调用XRt1553B_WriteMem两次（数据写入+指针重置）
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr, ((u16*)testData)[0]);
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr+1, ((u16*)testData)[1]);

    // 指针重置调用
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, XRT53_LUT_A_TX(subAddr), startPtr);
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, XRT53_LUT_B_TX(subAddr), startPtr);

    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, testData, byteLength);

    TEST_ASSERT_EQUAL(4, result);
}

/**
 * @brief TC005: 测试非循环缓冲区模式下不执行指针重置
 * 预期结果: 不执行指针重置操作
 */
void test_XRt1553B_TxToSubAddr_InNormalMode_ShouldNotResetPointers(void)
{
    u32 subAddr = 5;
    u32 byteLength = 4;
    u32 startPtr = 0x400;

    // 配置测试环境
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = 10;
    testInstance.tx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    testInstance.tx_SAcfg[subAddr].mm_mode = XRT53_MM_SINGLE_MSG; // 非循环模式

    // 期望只调用XRt1553B_WriteMem进行数据写入
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr, ((u16*)testData)[0]);
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr+1, ((u16*)testData)[1]);

    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, testData, byteLength);

    TEST_ASSERT_EQUAL(4, result);
}


/**
 * @brief TC006: Test with zero byte length
 * Expected result: Returns 0, no memory operations performed
 */
void test_XRt1553B_TxToSubAddr_WithZeroByteLength_ShouldReturnZero(void)
{
    u32 subAddr = 1;
    u32 byteLength = 0;
    
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = 10;
    
    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, testData, byteLength);
    
    TEST_ASSERT_EQUAL(0, result);
}


/**
 * @brief TC007: Test with maximum valid data length
 * Expected result: Successfully transmits all data
 */
void test_XRt1553B_TxToSubAddr_WithMaximumValidLength_ShouldTransmitAllData(void)
{
    u32 subAddr = 2;
    u32 byteLength = 20; // Assuming this is at or near max valid
    u32 startPtr = 0x100;
    
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = byteLength;
    testInstance.tx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    
    // Expect all data to be written
    for (int i = 0; i < byteLength/2; i++) {
        XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr + i, ((u16*)testData)[i]);
    }
    
    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, testData, byteLength);
    
    TEST_ASSERT_EQUAL(byteLength, result);
}


/**
 * @brief TC008: Test with byte length exactly equal to valid data bytes
 * Expected result: Successfully transmits all data
 */
void test_XRt1553B_TxToSubAddr_ExactValidDataBoundary_ShouldTransmitAllData(void)
{
    u32 subAddr = 3;
    u32 byteLength = 8;
    u32 startPtr = 0x200;
    
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = byteLength; // Exactly matching
    testInstance.tx_SAcfg[subAddr].DataBlock_start_ptr = startPtr;
    
    for (int i = 0; i < byteLength/2; i++) {
        XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr + i, ((u16*)testData)[i]);
    }
    
    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, testData, byteLength);
    
    TEST_ASSERT_EQUAL(byteLength, result);
}


/**
 * @brief TC010: Test with special sub-address values (0 and 31)
 * Expected result: Functions correctly with boundary sub-addresses
 */
void test_XRt1553B_TxToSubAddr_WithBoundarySubAddresses_ShouldWorkCorrectly(void)
{
    u32 byteLength = 4;
    u32 startPtr = 0x300;
    
    // Test sub-address 0
    testInstance.tx_SAcfg[0].valid_data_bytes = 10;
    testInstance.tx_SAcfg[0].DataBlock_start_ptr = startPtr;
    
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr, ((u16*)testData)[0]);
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr+1, ((u16*)testData)[1]);
    
    u32 result = XRt1553B_TxToSubAddr(&testInstance, 0, testData, byteLength);
    TEST_ASSERT_EQUAL(4, result);
    
    // Test sub-address 31
    testInstance.tx_SAcfg[31].valid_data_bytes = 10;
    testInstance.tx_SAcfg[31].DataBlock_start_ptr = startPtr;
    
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr, ((u16*)testData)[0]);
    XRt1553B_WriteMem_Expect(testInstance.BaseAddress, startPtr+1, ((u16*)testData)[1]);
    
    result = XRt1553B_TxToSubAddr(&testInstance, 31, testData, byteLength);
    TEST_ASSERT_EQUAL(4, result);
}


/**
 * @brief TC011: Test with NULL data pointer
 * Expected result: Handles NULL pointer gracefully (implementation dependent)
 */
void test_XRt1553B_TxToSubAddr_WithNullPointer_ShouldHandleGracefully(void)
{
    u32 subAddr = 1;
    u32 byteLength = 4;
    
    testInstance.tx_SAcfg[subAddr].valid_data_bytes = 10;
    testInstance.tx_SAcfg[subAddr].DataBlock_start_ptr = 0x100;
    
    // Depending on implementation, this might be expected to crash or be handled
    // If the function should handle NULL gracefully:
    u32 result = XRt1553B_TxToSubAddr(&testInstance, subAddr, NULL, byteLength);
    // Assertions would depend on expected behavior
}